import React, { Component } from 'react'

// import axios from 'axios'

import classNames from 'classnames'

import { NavBar, Icon } from 'antd-mobile'

import HouseItem from '../../components/HouseItem' 

import { getCurrentCity, API } from '../../utils'

import './index.css'
// 导入 CSSMoudles 样式文件
import styles from './index.module.scss'
// console.log(styles);

// style ===> { cls: "Map_cls__1o6sE" }
// 键： 我们自己写的类名称
// 值： CSSModules帮我们生成的样式名称（ 这个类名就是全局唯一的 ）


const labelStyle = {
  cursor: 'pointer',
  border: '0px solid rgb(255, 0, 0)',
  padding: '0px',
  whiteSpace: 'nowrap',
  fontSize: '12px',
  color: 'rgb(255, 255, 255)',
  textAlign: 'center'
}

export default class Map extends Component {
  state = {
    // 是否显示小区下的房源列表
    isShowList: false,
    // 小区房源列表数据
    houseList: []
  }
  async componentDidMount() {
    // const options = {
    //   enableHighAccuracy: true,
    //   timeout: 5000,
    //   maximumAge: 0
    // }
    // function success(pos) {
    //   // longitude 经度
    //   // latitude 维度
    //   var crd = pos.coords;
    //   var point = new window.BMap.Point(crd.latitude, crd.longitude);
    //   var geoc = new window.BMap.Geocoder();
    //   geoc.getLocation(point, function (rs) {
    //     var addComp = rs.addressComponents;
    //     console.log(addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber);
    //   })
    //   console.log('Your current position is:')
    //   console.log(`Latitude : ${crd.latitude}`)
    //   console.log(`Longitude: ${crd.longitude}`)
    //   console.log(`More or less ${crd.accuracy} meters.`)
    // }
    // function error(err) {
    //   console.warn(`ERROR(${err.code}): ${err.message}`)
    // }
    // navigator.geolocation.getCurrentPosition(success, error, options)

    // 创建地图实例  
    const map = new window.BMap.Map("container")
    this.map = map
    // 创建地址解析器实例   北京市海淀区上地10街 ==> 
    const myGeo = new window.BMap.Geocoder()
    // const point = new window.BMap.Point(121.61974989465013, 31.040136952343083)
    const { label, value } = await getCurrentCity()
    // 创建点坐标  
    // map.centerAndZoom(point, 15)
    // 第一个参数：可以省略，表示该城市的默认位置（ 市中心 ）
    // 第二个参数：回调函数，会在地址解析后，通过参数拿到坐标
    // 第三个参数：定位的城市名称
    myGeo.getPoint(
      null,
      async point => {
        if (point) {
          // 3 // 初始化地图，设置中心点坐标和地图级别
          map.centerAndZoom(point, 11)

          // 添加控件
          map.addControl(new window.BMap.NavigationControl())
          map.addControl(new window.BMap.ScaleControl())

          // 根据经纬度获取当前坐标城市
          // var point = new window.BMap.Point(121.61974989465013, 31.040136952343083);
          // var geoc = new window.BMap.Geocoder();
          // geoc.getLocation(point, function (rs) {
          //   var addComp = rs.addressComponents;
          //   console.log(addComp);
          //   map.setCurrentCity(addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber); // 仅当设置城市信息时，MapTypeControl的切换功能才能可用   
          // })

          // var marker = new window.BMap.Marker(point) // 创建标注    
          // map.addOverlay(marker)

          // map.enableScrollWheelZoom();   //启用滚轮放大缩小，默认禁用
          // map.enableContinuousZoom();    //启用地图惯性拖拽，默认禁用
          // 添加一个平移缩放控件、一个比例尺控件和一个缩略图控件
          // map.addControl(new window.BMap.NavigationControl());
          // map.addControl(new window.BMap.ScaleControl());
          // map.addControl(new window.BMap.OverviewMapControl());
          // map.addControl(new window.BMap.MapTypeControl());
          // map.setCurrentCity(label); // 仅当设置城市信息时，MapTypeControl的切换功能才能可用  

          this.renderOverlays(value)
        }
      },
      label
    )
  }

  // 作用：获取下一级的放大级别 和 覆盖物类型
  getTypeAndZoom() {
    // 获取当前地图的放大级别
    // console.log('当前地图的放大级别：', this.map.getZoom())
    const curZoom = this.map.getZoom()
    let nextZoom, type
    if (curZoom === 11) {
      // 当前为 11 ，也就是 圆形的
      type = 'circle'
      // 下一级：
      nextZoom = 13
    } else if (curZoom === 13) {
      // 当前为 13 ，也就是 圆形的
      type = 'circle'
      // 下一级：
      nextZoom = 15
    } else {
      // 当前为 15 ，也就是 矩形的
      type = 'rect'
    }

    return {
      nextZoom,
      type
    }
  }
  // 发送请求，获取指定区域的房源数据
  // 参数： 表示获取哪一个区域下的房源数据（ 区域id ）
  async renderOverlays(id) {
    const res = await API.get('http://localhost:8080/area/map', {
      params: {
        id
      }
    })

    // 获取房源类型 以及 下一级放大级别
    const { nextZoom, type } = this.getTypeAndZoom()
    // console.log(nextZoom, type)

    // 遍历所有的房源数据，为每一个房源数据创建一个覆盖物
    res.data.body.forEach(item => {
      // 调用创建覆盖物的方法
      this.createOverlays(item, nextZoom, type)
    })
  }

  // 根据 type 也就是房源覆盖物的类型来决定要渲染哪种覆盖物
  createOverlays(houseData, nextZoom, type) {
    const {
      coord: { latitude, longitude },
      count,
      label: areaName,
      value: areaId
    } = houseData

    // 根据数据中的房源坐标，创建 坐标对象
    const point = new window.BMap.Point(longitude, latitude)

    // 根据 type 也就是覆盖物类型，来决定调用哪一个方法渲染覆盖物
    if (type === 'circle') {
      // 圆形
      this.createCircle(point, areaName, count, areaId, nextZoom)
    } else {
      // 矩形覆盖物
      this.createRect(point, areaName, count, areaId)
    }
  }

  // 渲染圆形的覆盖物（ 区、镇 ）
  createCircle(point, areaName, count, areaId, nextZoom) {
    // 渲染地图覆盖物
    const opts = {
      // 坐标，也就是要把覆盖物渲染在地图中的哪个位置
      position: point,
      // 设置覆盖物的偏移
      offset: new window.BMap.Size(-35, -35)
    }

    // Label 就是一个覆盖物
    const label1 = new window.BMap.Label('', opts)

    // 设置 label 的 html 内容
    // 注意：此处内容为纯 HTML，所以，需要使用 class 来设置样式
    label1.setContent(`
      <div class="${styles.bubble}">
        <p class="${styles.name}">${areaName}</p>
        <p>${count}套</p>
      </div>
    `)

    // 设置覆盖物的样式
    label1.setStyle(labelStyle)

    // 给覆盖物绑定事件
    label1.addEventListener('click', () => {
      // console.log('覆盖物被点击了', areaId, nextZoom)

      // 发送请求，获取并渲染下一级房源覆盖物数据
      this.renderOverlays(areaId)

      // 放大地图
      this.map.centerAndZoom(point, nextZoom)

      // 清除现有覆盖物
      // 注意：需要延迟清除地图中的覆盖物。 因为在触发单击事件的时候，会把地图中所有的覆盖物全部清除
      //      而实际上，百度地图内容会做一些其他处理，需要用到这些覆盖物对象。所以，如果先清除覆盖物就会
      //      导致，百度地图内部在做处理时，找不到覆盖物，所以，就会报错！
      //
      //      解决方式： 延迟清除覆盖物，先让百度地图内部，把所有的其他处理先执行完成，然后，再清除覆盖物
      //                就可以解决这个报错的问题了。
      setTimeout(() => {
        this.map.clearOverlays()
      }, 0)
    })

    // 将创建好的覆盖物添加到地图中
    this.map.addOverlay(label1)
  }

  // 渲染矩形的覆盖物（ 小区 ）
  createRect(point, areaName, count, areaId) {
    // 渲染地图覆盖物
    const opts = {
      // 坐标，也就是要把覆盖物渲染在地图中的哪个位置
      position: point,
      // 设置覆盖物的偏移
      offset: new window.BMap.Size(-35, -35)
    }

    // Label 就是一个覆盖物
    const label1 = new window.BMap.Label('', opts)

    // 小区覆盖物结构：
    label1.setContent(`
      <div class="${styles.rect}">
        <span class="${styles.housename}">${areaName}</span>
        <span class="${styles.housenum}">${count}套</span>
        <i class="${styles.arrow}"></i>
      </div>
    `)

    // 设置覆盖物的样式
    label1.setStyle(labelStyle)

    // 给覆盖物绑定事件
    label1.addEventListener('click', e => {
      // console.log('小区覆盖物被点击了', areaId)
      // 当前点的 x 和 y坐标：
      const { clientX, clientY } = e.changedTouches[0]

      const x = window.innerWidth / 2 - clientX
      const y = (window.innerHeight - 330) / 2 - clientY

      // 公式：
      //  水平方向的偏移值为： 中心点的x - 当前点的x
      //  垂直方向的偏移值为： 中心点的y - 当前点的y
      //
      // 中心点坐标：( window.innerWidth / 2, (window.innerHeight - 330) / 2 )

      this.map.panBy(x, y)
      this.getHouses(areaId)
      this.setState({
        // 展示小区列表
        isShowList: true
      })
    })

    // 将创建好的覆盖物添加到地图中
    this.map.addOverlay(label1)
  }
  async getHouses(cityId) {
    const res = await API.get('http://localhost:8080/houses', {
      params: {
        cityId
      }
    })

    this.setState({
      houseList: res.data.body.list
    })
  }
  // 渲染小区列表数据
  renderHouseList() {
    return this.state.houseList.map(item => (
      <HouseItem {...item} key={item.houseCode}></HouseItem>
    ))
  }
  render() {
    return (
      <div className={styles.map}>
        <div className={styles.citylist}>
          <NavBar
            className={styles.navbar}
            // 模式：亮色调
            mode="light"
            // 图标
            icon={<Icon type="left" style={{fontSize: '16px'}} />}
            // 导航左边点击回调
            onLeftClick={() => this.props.history.push('/home')}
          // 导航右边内容
          // rightContent={[
          //   <Icon key="0" type="search" style={{ marginRight: '16px' }} />,
          //   <Icon key="1" type="ellipsis" />,
          // ]}
          >地图找房</NavBar>
        </div>
        <div id="container" className={styles.container}></div>
        {/* 小区中的房源列表结构 */}
        <div
          className={classNames(styles.houseList, {
            [styles.show]: this.state.isShowList
          })}
        >
          <div className={styles.titleWrap}>
            <h1 className={styles.listTitle}>房屋列表</h1>
            <a className={styles.titleMore} href="/home/houselist">
              更多房源
            </a>
          </div>
        <div className={styles.houseItems}>{this.renderHouseList()}</div>
        </div>
      </div>
    )
  }
}
